<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */
namespace Application;

use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Application\Model\Category;
use Application\Model\CategoryTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Application\Model\ProductTable;
use Application\Model\Image;
use Application\Model\Session;
use Application\Model\Order;
use Application\Model\OrderTable;
use Application\Model\Users;
use Application\Model\UsersTable;
use Application\Model\OrderProduct;
use Application\Model\OrderProductTable;
use Application\Model\ImageTable;
use Application\Model\Product;

class Module
{

    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'Zend\Session\SessionManager' => function ($sm)
                {
                    $config = $sm->get('config');
                    if (isset($config['session'])) {
                        $session = $config['session'];

                        $sessionConfig = null;
                        if (isset($session['config'])) {
                            $class = isset($session['config']['class']) ? $session['config']['class'] : 'Zend\Session\Config\SessionConfig';
                            $options = isset($session['config']['options']) ? $session['config']['options'] : array();
                            $sessionConfig = new $class();
                            $sessionConfig->setOptions($options);
                        }

                        $sessionStorage = null;
                        if (isset($session['storage'])) {
                            $class = $session['storage'];
                            $sessionStorage = new $class();
                        }

                        $sessionSaveHandler = null;
                        if (isset($session['save_handler'])) {
                            // class should be fetched from service manager since it will require constructor arguments
                            $sessionSaveHandler = $sm->get($session['save_handler']);
                        }

                        $sessionManager = new SessionManager($sessionConfig, $sessionStorage, $sessionSaveHandler);

                        if (isset($session['validator'])) {
                            $chain = $sessionManager->getValidatorChain();
                            foreach ($session['validator'] as $validator) {
                                $validator = new $validator();
                                $chain->attach('session.validate', array(
                                    $validator,
                                    'isValid'
                                ));
                            }
                        }
                    } else {
                        $sessionManager = new SessionManager();
                    }
                    Container::setDefaultManager($sessionManager);
                    return $sessionManager;
                },

                'Application\Model\CategoryTable' => function ($sm)
                {
                    $tableGateway = $sm->get('CategoryTableGateway');
                    $table = new CategoryTable($tableGateway);
                    return $table;
                },
                'CategoryTableGateway' => function ($sm)
                {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Category());
                    return new TableGateway('category', $dbAdapter, null, $resultSetPrototype);
                },

                'Application\Model\ProductTable' => function ($sm)
                {
                    $tableGateway = $sm->get('ProductTableGateway');
                    $table = new ProductTable($tableGateway);
                    return $table;
                },
                'ProductTableGateway' => function ($sm)
                {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Product());
                    return new TableGateway('product', $dbAdapter, null, $resultSetPrototype);
                },
                'Application\Model\ImageTable' => function ($sm)
                {
                    $tableGateway = $sm->get('ImageTableGateway');
                    $table = new ImageTable($tableGateway);
                    return $table;
                },
                'ImageTableGateway' => function ($sm)
                {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Image());
                    return new TableGateway('image', $dbAdapter, null, $resultSetPrototype);
                },
                'Application\Model\SessionTable' => function ($sm)
                {
                    $tableGateway = $sm->get('SessionTableGateway');
                    $table = new SessionTable($tableGateway);
                    return $table;
                },
                'SessionTableGateway' => function ($sm)
                {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Session());
                    return new TableGateway('session', $dbAdapter, null, $resultSetPrototype);
                },
                'Application\Model\OrderTable' => function ($sm)
                {
                    $tableGateway = $sm->get('OrderTableGateway');
                    $table = new OrderTable($tableGateway);
                    return $table;
                },
                'OrderTableGateway' => function ($sm)
                {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Order());
                    return new TableGateway('order', $dbAdapter, null, $resultSetPrototype);
                },
                'Application\Model\OrderProductTable' => function ($sm)
                {
                    $tableGateway = $sm->get('OrderProductTableGateway');
                    $table = new OrderProductTable($tableGateway);
                    return $table;
                },
                'OrderProductTableGateway' => function ($sm)
                {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new OrderProduct());
                    return new TableGateway('order_product', $dbAdapter, null, $resultSetPrototype);
                },
                'Application\Model\UsersTable' => function ($sm)
                {
                    $tableGateway = $sm->get('UsersTableGateway');
                    $table = new UsersTable($tableGateway);
                    return $table;
                },
                'UsersTableGateway' => function ($sm)
                {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Users());
                    return new TableGateway('users', $dbAdapter, null, $resultSetPrototype);
                }
            )
        );
    }

    public function onBootstrap(MvcEvent $e)
    {
        $e->getApplication()
            ->getServiceManager()
            ->get('translator');
        $eventManager = $e->getApplication()->getEventManager();
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);
    }

    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__
                )
            )
        );
    }

    public function bootstrapSession($e)
    {
//         $session = $e->getApplication()
//             ->getServiceManager()
//             ->get('Zend\Session\SessionManager');
//         $session->start();

//         $container = new Container('initialized');
//         if (! isset($container->init)) {
//             $session->regenerateId(true);
//             $container->init = 1;
//         }

        // grab the config array
        $config = $e->getApplication()->getServiceManager()->get('config');
        // get the database section
        $dbAdapter = new \Zend\Db\Adapter\Adapter($config['db']);

        // get the session options (column names)
        $sessionOptions = new \Zend\Session\SaveHandler\DbTableGatewayOptions($config['session_config']);

        // crate the TableGateway object specifying the table name
        $sessionTableGateway = new \Zend\Db\TableGateway\TableGateway('session', $dbAdapter);
        // create your saveHandler object
        $saveHandler = new \Zend\Session\SaveHandler\DbTableGateway($sessionTableGateway, $sessionOptions);

        // pass the saveHandler to the sessionManager and start the session
        $sessionManager = new \Zend\Session\SessionManager(NULL, NULL, $saveHandler);
        $sessionManager->start();
    }
}
